#!/usr/bin/env python
################################################################
# simpledb: a simple mysql db wrapper module with auto connect
#
# Author: Curu Wong
# Date:   2014-08-25
# License: GPL v3
##########################################################
import sys,time
import MySQLdb
from MySQLdb.cursors import DictCursor
import functools

class SimpleDB:
    def __init__(self, host, user, password, db_name, port = 3306, charset='utf8'):
        self.db_info = { 'host' : host, 'user' : user, 'password' : password, 'db' : db_name, 'port' : port, 'charset' : charset }
        self.connect()

    def __del__(self):
        try:
            if self.cursor:
                self.cursor.close()
            if self.conn:
                self.conn.close()
        except Exception:
            pass

    def auto_reconnect(func):
        def wrapper(self, *args, **kwargs):
            try:
                return func(self, *args, **kwargs)
            except MySQLdb.Error as e:
                self.connect()
                return func(self, *args, **kwargs)
        functools.update_wrapper(wrapper, func)
        return wrapper

    def connect(self):
        self.conn = MySQLdb.connect(self.db_info['host'], self.db_info['user'], self.db_info['password'], self.db_info['db'],
            self.db_info['port'], connect_timeout=10, charset=self.db_info['charset'])
        self.cursor = self.conn.cursor()

    @auto_reconnect
    def commit(self):
        """commit(self)"""
        self.conn.commit()

    @auto_reconnect
    def execute_sql(self, sql, args=None):
        "execute_sql(self, sql, args=None)"""
        self.cursor.execute(sql, args)
        self.conn.commit()

    @auto_reconnect
    def execute_sql_no_commit(self, sql, args=None):
        """execute_sql_no_commit(self, sql, args=None)"""
        self.cursor.execute(sql, args)

    @auto_reconnect
    def get_one(self, sql, args=None, cursorclass=None):
        """get_one(self, sql, args=None, cursorclass=None)"""
        cursor = self.conn.cursor(cursorclass)
        cursor.execute(sql, args)
        return cursor.fetchone()

    def get_one_dict(self, sql, args=None):
        return self.get_one(sql, args, cursorclass=DictCursor)

    @auto_reconnect
    def get_all(self, sql, args=None, cursorclass=None):
        """get_all(self, sql, args=None, cursorclass=None)"""
        cursor = self.conn.cursor(cursorclass)
        cursor.execute(sql, args)
        return cursor.fetchall()

    def get_all_dict(self, sql, args=None):
        return self.get_all(sql, args, cursorclass=DictCursor)
